package com.liuqianfei.markme.rules.block;

import com.liuqianfei.markme.common.HTMLBlocks;
import com.liuqianfei.markme.common.HTMLRe;
import com.liuqianfei.markme.core.Token;
import com.liuqianfei.markme.rules.AbstractState;
import com.liuqianfei.markme.rules.IAction;
import com.liuqianfei.util.RegExpUtil;
import com.liuqianfei.util.StringUtil;

/**
 * HTML block
 * @author liuqianfei
 */
public class HtmlBlockAction implements IAction
{
    String[][] HTML_SEQUENCES = {
            {"^<(script|pre|style)(?=(\\s|>|$))", "<\\/(script|pre|style)>", "true" },
            { "^<!--",        "-->",   "true" },
            { "^<\\?",         "\\?>",   "true" },
            { "^<![A-Z]",     ">",     "true" },
            { "^<!\\[CDATA\\[", "\\]\\]>", "true" },
            { "^</?(" + String.join("|", HTMLBlocks.block_names) + ")(?=(\\s|/?>|$))", "^$", "true" },
            { HTMLRe.HTML_OPEN_CLOSE_TAG_RE + "\\s*$", "^$", "false" }
    };

    @Override
    public boolean parse(AbstractState state, boolean silent, int startLine, int endLine)
    {
        String lineText;
        Token token;
        int i, nextLine, pos = state.getbMarks(startLine) + state.gettShift(startLine), max = state.geteMarks(startLine);

        if (!state.getMd().configuration.html)
            return false;

        if (state.getSrc().charAt(pos) != 0x3C/* < */)
            return false;

        lineText = StringUtil.slice(state.getSrc(), pos, max);

        for (i = 0; i < HTML_SEQUENCES.length; i++)
        {
            if (RegExpUtil.match(HTML_SEQUENCES[i][0], lineText, true))
                break;
        }

        if (i == HTML_SEQUENCES.length)
            return false;

        if (silent)
        {
            // true if this sequence can be a terminator, false otherwise
            return Boolean.valueOf(HTML_SEQUENCES[i][2]);
        }

        nextLine = startLine + 1;

        // If we are here - we detected HTML block.
        // Let's roll down till block end.
        if (!RegExpUtil.match(HTML_SEQUENCES[i][1], lineText, true))
        {
            for (; nextLine < endLine; nextLine++)
            {
                if (state.getsCount(nextLine) < state.getBlkIndent())
                    break;

                pos = state.getbMarks(nextLine) + state.gettShift(nextLine);
                max = state.geteMarks(nextLine);
                lineText = StringUtil.slice(state.getSrc(), pos, max);

                if (RegExpUtil.match(HTML_SEQUENCES[i][1], lineText, true))
                {
                    if (lineText.length() != 0)
                        nextLine++;
                    break;
                }
            }
        }

        state.setLine(nextLine);

        token         = state.push("html_block", "", 0);
        token.map     = new int[]{startLine, nextLine};
        token.content = state.getLines(startLine, nextLine, state.getBlkIndent(), true);

        return true;
    }
}
